#include "app_param.h"

#define param_printf printf

static void param_save_in_device(uint8_t *params,uint16_t len);
static void param_read_from_device(uint8_t *params,uint16_t len);
static void param_define_default(const char *name,const void *value,param_type_e type);

static struct param_info_s param_list_head =
{
    "param_list_head",  //name
    0,					//counts
    PARAM_TYPE_INVALID, //type
    0,					//value
    0,					//value
    0,					//next
};

static uint8_t param_init_ok = 0;

void param_init(void)
{
	param_init_ok = 1;
	
	param_define_default_int("CAM_ZERO_OSD_STATUS",CAM_ZERO_OSD_STATUS);
	param_define_default_float("ROCK_VAL_MID",ROCK_VAL_MID);
}

void param_define_default_int(const char *name,const int value)
{
	param_define_default(name,&value,PARAM_TYPE_INT);
}

void param_define_default_float(const char *name, const float value)
{
	param_define_default(name,&value,PARAM_TYPE_FLOAT);
}

//char *type->param_type_e
static void param_define_default(const char *name,const void *value,param_type_e type)
{
	if(!name || !value) return;
	
	struct param_info_s *ptr = 0;
	struct param_info_s *new_param = 0;
	uint8_t error = 0;
	uint8_t get_type = type;

	ptr = &param_list_head;
	ptr->param_counts++;

	while(ptr->next != 0)
  {    
		ptr = ptr->next;
		if(strcmp(name,ptr->name) == 0)
		{
			error = 1;
			break;
		}
  }

	if(error == 0)
	{
		new_param = (struct param_info_s*)malloc(sizeof(struct param_info_s) );
		if(!new_param) 
		{
			param_printf("xxxxxx [%s]param default new params fault.\r\n",name);
			return;
		}

		memcpy(new_param->name,name,strlen(name));//less than 32
		switch(get_type)
		{
			case PARAM_TYPE_INT:
				new_param->val_int = *(int*)value;
				new_param->val_float = 0;
				break;
			case PARAM_TYPE_FLOAT:
				new_param->val_float = *(float*)value;
				new_param->val_int = 0;
				break;
		}
		new_param->type = type;
		new_param->next = 0;

		ptr->next = new_param;

		#if 0
		float val_float = ptr->next->val_float;
		int val_int = ptr->next->val_int;
		switch(get_type)
		{
			case PARAM_TYPE_INT:
				param_printf("[%s],value:%d\r\n",name,val_int);
				break;
			case PARAM_TYPE_FLOAT:
				param_printf("[%s],value:%f\r\n",name,val_float);
				break;
		}
		#endif
	}
	else
	{
		param_printf("xxxxxx[%s]param already define.\r\n",name);
	}
}

void param_get(const char *name,void *value)
{
	if(!name || !value || !param_init_ok) return;
	
	struct param_info_s *ptr = 0;
	uint8_t can_find = 0;

	ptr = &param_list_head;

	while(ptr->next != 0)
  {    
		ptr = ptr->next;
		
		if(strcmp(name,ptr->name) == 0)
		{
			can_find = 1;
			break;
		}
  }

	if(can_find)
	{
		uint8_t get_type = ptr->type;
		switch(get_type)
		{
			case PARAM_TYPE_INT:
				*(int*)value = ptr->val_int;
				param_printf("[%s],value:%d\r\n",name,*(int*)value);
				break;
			case PARAM_TYPE_FLOAT:
				*(float*)value = ptr->val_float;
				param_printf("[%s],value:%f\r\n",name,*(float*)value);
				break;
		}
	}
}

void param_set(const char *name,void *value,param_type_e type)
{
	if(!name || !value) return;
	
	struct param_info_s *ptr = 0;
	uint8_t can_find = 0;

	ptr = &param_list_head;

	while(ptr->next != 0)
    {    
		ptr = ptr->next;
		
		if(strcmp(name,ptr->name) == 0)
		{
			can_find = 1;
			break;
		}
    }

	if(can_find)
	{
		uint8_t get_type = ptr->type;
		switch(get_type)
		{
			case PARAM_TYPE_INT:
				ptr->val_int = *(int*)value;
				break;
			case PARAM_TYPE_FLOAT:
				ptr->val_float = *(float*)value;
				break;
		}
	}
}

void param_save_all(void)
{
	struct param_info_s *ptr = 0;
	uint16_t total_counts = 0;
	uint16_t total_sizes = 0;
	uint8_t copy_buf[128] = {0};
	uint8_t check_sum = 0;
	uint16_t loop_cnt = 0;
	uint16_t offset = 0;

	uint8_t packs = 0;
	uint16_t pack_size = 512;

	ptr = &param_list_head;
	total_counts = ptr->param_counts;
	total_sizes = total_counts*PARAM_ONE_SIZE;

	packs = total_sizes/pack_size;
	if(total_sizes%pack_size)	packs++;

	copy_buf[0] = 0xaa;
	copy_buf[1] = 0xbb;

	while(ptr->next != 0 && loop_cnt < total_counts)
    {    
		ptr = ptr->next;
		check_sum += ptr->val_float;
		check_sum += ptr->val_int;
		copy_buf[2] = check_sum;
		
		memcpy((&copy_buf[3])+offset,ptr,PARAM_ONE_SIZE);
		param_save_in_device(copy_buf,PARAM_ONE_SIZE);
		memset(&copy_buf[2],0,128-2);

		loop_cnt++;
		//offset += PARAM_ONE_SIZE;
    }
}

uint8_t param_load_all(void)
{
	struct param_info_s *ptr = 0;
	uint16_t total_counts = 0;
	uint16_t sizes = 0;
	uint8_t read_buf[128] = {0};

	ptr = &param_list_head;
	total_counts = ptr->param_counts;
	sizes = total_counts*PARAM_ONE_SIZE;

	while(ptr->next != 0)
  {    
		ptr = ptr->next;
		
		param_read_from_device(read_buf,PARAM_ONE_SIZE);
		
		memcpy(ptr,read_buf,PARAM_ONE_SIZE);
		memset(read_buf,0,128);
  }
	
	return 1;
}


static void param_save_in_device(uint8_t *params,uint16_t len)
{
	//todo
}

static void param_read_from_device(uint8_t *params,uint16_t len)
{
	//todo
}



